package com.atguigu.srb.core.service.impl;

import com.alibaba.excel.EasyExcel;
import com.atguigu.guigu.common.exception.BusinessException;
import com.atguigu.guigu.common.result.ResultCodeEnum;
import com.atguigu.srb.core.listener.DictExcelDataListener;
import com.atguigu.srb.core.pojo.entity.Dict;
import com.atguigu.srb.core.mapper.DictMapper;
import com.atguigu.srb.core.pojo.entity.excel.DictData;
import com.atguigu.srb.core.service.DictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * <p>
 * 数据字典 服务实现类
 * </p>
 *
 * @author Atguigu
 * @since 2022-11-19
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {
    @Resource
    RedisTemplate redisTemplate;
    //常见的自定义javabean类型： vo:view object    dto:data transfer object
    // query/search: 前端查询过滤提交的数据    excel
    @Override
    public void importDicts(MultipartFile excel) {
        //解析excel文件中的数据 一行转为一个Dict对象存入到dict表中
        //1、为要读取的excel文件创建映射的javabean
        //2、创建监听器 处理每一行加载到的数据(保存数据到数据库)
        //3、使用easyexcel配置读取数据
        try {
            InputStream inputStream = excel.getInputStream();
            EasyExcel.read(inputStream)
                    .sheet(0)
                    .head(DictData.class)
                    .registerReadListener(new DictExcelDataListener(baseMapper))
                    .doRead();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(ResultCodeEnum.UPLOAD_ERROR,e);
        }

    }
//    @CacheEvict 让缓存失效的注解
//    @Cacheable(value = "dicts" , key = "'cache'") //拼接后的key为 dicts::cache
    @Cacheable(value = "dicts" , key = "'cache:'+{#parentId}") //拼接后的key为 dicts::cache:parentId的值
    @Override
    public List<Dict> getDictsByPid(String parentId) {
        //2、如果redis中没有缓存 查询数据库
        List<Dict> dicts = this.list(new LambdaQueryWrapper<Dict>()
                .eq(Dict::getParentId, parentId));
        //遍历为每一个数据字典提供hasChildren属性值 如果有下一级设置为true
        /*
            数据库表映射的bean 满足不了前端的需求，解决方案：
                1、自定义一个类继承Dict 在自定义类中扩展其他属性
                2、直接在javabean中添加属性，新增的属性需要指定不是数据库表中的字段
         */
        dicts.forEach(dict->{
            int count = this.count(new LambdaQueryWrapper<Dict>()
                    .eq(Dict::getParentId, dict.getId()));
            dict.setHasChildren(count>0);
        });
        //4、返回数据集合
        return dicts;
    }
    @CacheEvict(value = "dicts" , key = "'cache:'+{#dict.parentId}")
    @Override
    public void updateDict(Dict dict) {
        this.updateById(dict);
    }

    @Override
    public List<Dict> getDictsByDictCode(String dictCode) {
        return baseMapper.selectDictsByDictCode(dictCode);
    }

    @Override
    public String getDictNameByDictCodeAndValue(String dictCode, Integer value) {

        return baseMapper.selectDictNameByDictCodeAndValue(dictCode,value);
    }

//    @Override
//    public List<Dict> getDictsByPid(String parentId) {
//        //1、查询redis中的缓存，如果有直接返回
//        Object obj = redisTemplate.opsForValue().get("dicts:" + parentId);
//        if(obj!=null){
//            return (List<Dict>) obj;
//        }
//        //2、如果redis中没有缓存 查询数据库
//        List<Dict> dicts = this.list(new LambdaQueryWrapper<Dict>()
//                .eq(Dict::getParentId, parentId));
//        //遍历为每一个数据字典提供hasChildren属性值 如果有下一级设置为true
//        /*
//            数据库表映射的bean 满足不了前端的需求，解决方案：
//                1、自定义一个类继承Dict 在自定义类中扩展其他属性
//                2、直接在javabean中添加属性，新增的属性需要指定不是数据库表中的字段
//         */
//        dicts.forEach(dict->{
//            int count = this.count(new LambdaQueryWrapper<Dict>()
//                    .eq(Dict::getParentId, dict.getId()));
//            dict.setHasChildren(count>0);
//        });
//        //3、将查询的数据存到redis中
//        redisTemplate.opsForValue().set("dicts:"+parentId ,dicts );
//        //4、返回数据集合
//        return dicts;
//    }
}
